package info.wangyuan.agent.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.Path;
import java.util.*;

/**
 * JSON 工具类
 *
 * @author Albert
 * @since 2025-08-16 17:28:47
 */
@Slf4j
public class JsonUtils {

    private static ObjectMapper objectMapper;

    /**
     * 复用全局定义的 ObjectMapper
     */
    public static void setObjectMapper(ObjectMapper objectMapper) {
        JsonUtils.objectMapper = objectMapper;
    }

    private JsonUtils() {
    }

    public static String toJsonString(Object obj) {
        if (obj == null) return "{}";
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            log.error("JSON序列化失败: {}, 错误: {}", obj.getClass().getSimpleName(), e.getMessage(), e);
            return "{}";
        }
    }

    public static <T> T parseObject(String json, Class<T> clazz) {
        if (json == null || json.isEmpty()) return null;
        try {
            return objectMapper.readValue(json, clazz);
        } catch (Exception e) {
            log.error("JSON反序列化失败: {}, 错误: {}", clazz.getSimpleName(), e.getMessage(), e);
            return null;
        }
    }

    public static <T> List<T> parseArray(String json, Class<T> clazz) {
        if (json == null || json.isEmpty()) return Collections.emptyList();
        try {
            JavaType type = objectMapper.getTypeFactory().constructCollectionType(List.class, clazz);
            return objectMapper.readValue(json, type);
        } catch (Exception e) {
            log.error("JSON数组反序列化失败: {}", e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    /**
     * 安全解析 JSON 为 Map<String, Object>
     * 避免 unchecked cast 和类型不一致问题
     */
    public static Map<String, Object> parseJsonToMap(String json) {
        if (json == null || json.isEmpty()) return Collections.emptyMap();
        try {
            Map<String, Object> result = objectMapper.readValue(
                    json, new TypeReference<Map<String, Object>>() {
                    });
            return result != null ? result : Collections.emptyMap();
        } catch (Exception e) {
            log.error("JSON Map反序列化失败: {}", e.getMessage(), e);
            return Collections.emptyMap();
        }
    }

    public static Map<String, Object> parseJsonToMap(Path path) {
        try {
            Map<String, Object> result = objectMapper.readValue(
                    path.toFile(), new TypeReference<Map<String, Object>>() {
                    });
            return result != null ? result : Collections.emptyMap();
        } catch (Exception e) {
            log.error("JSON Map反序列化失败: {}", e.getMessage(), e);
            return Collections.emptyMap();
        }
    }

    /**
     * 把对象安全写入Json
     */
    public static void writeJsonToFile(Path path, Object obj) throws IOException {
        try {
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(path.toFile(), obj);
        } catch (IOException e) {
            log.error("保存文件夹 [{}] 的元数据失败: {}", path, e.getMessage(), e);
            throw new IOException(e);
        }
    }

    /**
     * 获取 Map 中的 Set<Integer>，兼容 JSON 解析出来的 List 或 Set
     */
    public static Set<Integer> getIntegerSet(Map<String, Object> map, String key) {
        if (map == null || !map.containsKey(key)) return new HashSet<>();
        Object value = map.get(key);
        Set<Integer> result = new HashSet<>();

        if (value instanceof Iterable<?> iterable) {
            for (Object o : iterable) {
                if (o instanceof Number n) result.add(n.intValue());
                else if (o instanceof String s) {
                    try {
                        result.add(Integer.parseInt(s));
                    } catch (NumberFormatException ignored) {
                    }
                }
            }
        }
        return result;
    }

    /**
     * 获取 Map 中的布尔值，支持 null 默认值
     */
    public static boolean getBoolean(Map<String, Object> map, String key, boolean defaultValue) {
        if (map == null || !map.containsKey(key)) return defaultValue;
        Object value = map.get(key);
        if (value instanceof Boolean b) return b;
        if (value instanceof String s) return Boolean.parseBoolean(s);
        return defaultValue;
    }
}
